<template>
  <a-modal
    v-model:visible="show"
    centered
    destroy-on-close
    class="modal-login"
    width="360px"
    :mask-closable="false"
    :closable="false"
    :footer="null">
    <div v-if="form.scene === 'reg'" class="login-title login-reg" slot="title">
      <c-icon icon="LeftOutlined" class="pre-icon" @click.stop="form.scene = 'login'"></c-icon>
      <span>注册账号</span>
    </div>
    <div v-else-if="form.scene === 'forget'" class="login-title login-reg" slot="title">
      <c-icon icon="LeftOutlined" class="pre-icon" @click.stop="form.scene = 'login'"></c-icon>
      <span>忘记密码</span>
    </div>
    <div v-else class="login-title" slot="title">
      <div>
        <span><img src="upload.svg" class="inblock" width="20" /> CDN静态资源 | </span>
        <span>登录账号</span>
      </div>
      <c-icon icon="CloseOutlined" class="login-close pre-icon" @click.stop="closed"></c-icon>
    </div>

    <a-form ref="signRef" v-if="form.scene === 'reg'" :rules="rules" :model="signForm" class="login-form mt-12" layout="vertical">
      <div>
        <a-form-item label="" name="username">
          <a-input v-model:value="signForm.username" allowClear placeholder="用户名">
            <template #prefix>
              <c-icon icon="UserOutlined" class="pre-icon" />
            </template>
          </a-input>
        </a-form-item>
        <a-form-item label="" name="password">
          <a-input-password v-model:value="signForm.password" allowClear placeholder="密码">
            <template #prefix>
              <c-icon icon="LockOutlined" class="pre-icon" />
            </template>
          </a-input-password>
        </a-form-item>
        <a-form-item label="" name="confirmPass">
          <a-input-password v-model:value="signForm.confirmPass" allowClear placeholder="确认密码">
            <template #prefix>
              <c-icon icon="LockOutlined" class="pre-icon" />
            </template>
          </a-input-password>
        </a-form-item>
        <a-form-item label="" name="email">
          <a-input v-model:value="signForm.email" allowClear placeholder="邮箱">
            <template #prefix>
              <c-icon icon="MailOutlined" class="pre-icon" />
            </template>
          </a-input>
        </a-form-item>
        <a-form-item label="" name="code">
          <a-row :gutter="10">
            <a-col :span="15">
              <a-input v-model:value="signForm.code" allowClear placeholder="验证码">
                <template #prefix>
                  <c-icon icon="SafetyOutlined" class="pre-icon" />
                </template>
              </a-input>
            </a-col>
            <a-col :span="9">
              <captcha ref="captRef" :scene="signForm.scene" />
            </a-col>
          </a-row>
        </a-form-item>
      </div>

      <a-form-item class="login-form-btn">
        <a-button type="primary" block :loading="loading" @click.stop="handleSubmit"> 注册 </a-button>
        <div class="center tip"><span>已有账号，</span><span class="go-reg" @click.stop="form.scene = 'login'">去登录</span></div>
      </a-form-item>
    </a-form>
    <a-form ref="forRef" v-else-if="form.scene === 'forget'" :model="form" :rules="rules" class="login-form mt-12" layout="vertical">
      <div>
        <a-form-item label="" name="username">
          <a-input v-model:value="form.username" allowClear placeholder="用户名"></a-input>
        </a-form-item>
        <a-form-item label="" name="code">
          <a-row :gutter="10">
            <a-col :span="15">
              <a-input v-model:value="form.code" allowClear placeholder="验证码">
                <template #prefix>
                  <c-icon icon="SafetyOutlined" class="pre-icon" />
                </template>
              </a-input>
            </a-col>
            <a-col :span="9">
              <captcha ref="captRef" :scene="form.scene" />
            </a-col>
          </a-row>
        </a-form-item>
      </div>
      <a-form-item class="login-form-btn">
        <a-button type="primary" block :loading="loading" @click.stop="handleSubmit"> 忘记密码 </a-button>
        <div class="center tip"><span>邮箱接收重置密码链接，放弃</span><span class="go-reg" @click.stop="form.scene = 'login'">去登录</span></div>
      </a-form-item>
    </a-form>
    <a-form ref="formRef" v-else :rules="rules" :model="form" class="login-form" layout="vertical">
      <a-tabs class="" v-model:activeKey="activeKey">
        <a-tab-pane key="password" tab="账号登录">
          <a-form-item label="" name="username">
            <a-input v-model:value="form.username" allowClear placeholder="用户名">
              <template #prefix>
                <c-icon icon="UserOutlined" class="pre-icon"></c-icon>
              </template>
            </a-input>
          </a-form-item>
          <a-form-item label="" name="password">
            <a-input-password v-model:value="form.password" allowClear placeholder="密码">
              <template #prefix>
                <c-icon icon="LockOutlined" class="pre-icon"></c-icon>
              </template>
            </a-input-password>
          </a-form-item>
          <a-form-item label="" name="code">
            <a-row :gutter="10">
              <a-col :span="15">
                <a-input v-model:value="form.code" allowClear placeholder="验证码">
                  <template #prefix>
                    <c-icon icon="SafetyOutlined" class="pre-icon" />
                  </template>
                </a-input>
              </a-col>
              <a-col :span="9">
                <captcha ref="captRef" :scene="form.scene" />
              </a-col>
            </a-row>
          </a-form-item>
        </a-tab-pane>
        <a-tab-pane key="phone" tab="手机号登录">
          <a-form-item label="" name="phone">
            <a-input v-model:value="form.phone" allowClear placeholder="手机号">
              <template #prefix>
                <c-icon icon="PhoneOutlined" class="pre-icon" />
              </template>
            </a-input>
          </a-form-item>
          <a-form-item label="" name="code">
            <a-input v-model:value="form.code" allowClear placeholder="验证码">
              <template #prefix>
                <c-icon icon="SafetyOutlined" class="pre-icon" />
              </template>
              <template #suffix>
                <a-button type="primary" ghost size="small" @click.stop="validatePhone">{{codeTxt}}</a-button>
              </template>
            </a-input>
          </a-form-item>
        </a-tab-pane>
      </a-tabs>

      <a-form-item class="login-form-btn">
        <a-button type="primary" block :loading="loading" @click.stop="handleSubmit"> 登录 </a-button>
        <div v-if="activeKey === 'phone'" class="center tip">
          <span>手机验证码登录，无需注册</span>
        </div>
        <div v-else class="flex tip">
          <span class="go-reg" @click.stop="form.scene = 'forget'">忘记密码</span>
          <span>
            <span>还没有账号？</span>
            <span class="go-reg" @click.stop="form.scene = 'reg'">马上注册</span>
          </span>
        </div>
      </a-form-item>
    </a-form>

    <validate v-model:visible="captmodel" :scene="form.scene" @on-ok="handleSendSms"></validate>
    <a-modal v-model:visible="resulting" title="系统提示" destroy-on-close>
      <div class="pd-20">
        <p> <c-icon icon="CheckCircleOutlined" :style="{color: '#52c41a', fontSize: '26px'}" />  恭喜您！用户注册成功，请留意查收激活邮件。</p>
      </div>

      <template #footer>
        <a-button type="primary" @click.stop="resultClosed"> 知道了 </a-button>
      </template>
    </a-modal>
  </a-modal>
</template>
<script>
import WattTool from '@wattjs/tool'
import { defineComponent, ref, reactive, computed } from 'vue'
import { message } from 'ant-design-vue'
import { ll } from '../../utils'
import Captcha from '../common/captcha.vue'
import Validate from '../common/validate.vue'

import { userLogin, userRegister, sendSmsCode, loginBySmsCode, userForgetPassword } from '../../api/user.model'

function trim (str) {
  if (String.prototype.trim) {
    return str === null ? '' : String.prototype.trim.call(str)
  } else {
    return str.replace(/(^\s*)|(\s*$)/g, '')
  }
}
const isEmpty = (str) => {
  if (typeof str === 'undefined' || typeof str === 'null' || !(str === str) || str.toString().includes('NaN')) str = ''
  const reg = new RegExp(/^[\s]*$/)
  str = trim(str)
  return reg.test(str)
}

export default defineComponent({
  emits: ['update:visible'],
  components: { Captcha, Validate },
  props: {
    modelVisible: {
      type: Boolean,
      default: false
    }
  },
  setup (props, { emit }) {
    let DTIME
    const { modelVisible } = props
    const resulting = ref(false)
    const loading = ref(false)
    const activeKey = ref('phone')
    const coding = ref(false) // 倒计时中
    const codeTxt = ref('获取验证码')
    const captmodel = ref(false) // 短信验证码弹窗

    const captRef = ref()
    const formRef = ref()
    const forRef = ref()
    const signRef = ref()
    const form = reactive({
      username: '',
      password: '',
      code: '',
      scene: 'login'
    })
    const signForm = reactive({
      username: '',
      password: '',
      code: '',
      email: '',
      scene: form.scene
    })

    const rules = computed(() => {
      if (form.scene === 'reg') {
        return {
          username: [{
                      required: true,
                      min: 2,
                      max: 25,
                      pattern: '^[0-9a-zA-Z]+[_]*[0-9a-zA-Z]+$',
                      message: '账号为2-25个字母、数字、下划线组合字符'
                    }],
          password: [{
                      required: true,
                      min: 6,
                      max: 20,
                      pattern: '^[0-9a-zA-Z]+[_]*[0-9a-zA-Z]+$',
                      message: '密码为6-20个字母、数字、下划线组合字符'
                    }],
          confirmPass: [{
                      required: true,
                      validator: async (_rule, value) => {
                        if (isEmpty(value)) return Promise.reject('确认密码不能为空')
                        else if (value !== signForm.password) return Promise.reject('确认密码需与密码保持一致')
                        else Promise.resolve()
                      }
                    }],
          code: [{
                  required: true,
                  min: 4,
                  max: 4,
                  pattern: '[0-9a-zA-Z]{4}',
                  message: '请正确输入验证码'
                }],
          email: [{
                  required: true,
                  min: 2,
                  pattern: '^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$',
                  message: '请正确输入邮箱地址'
                }]
        }
      } else if (form.scene === 'forget') {
        return {
          username: [{
                    required: true,
                    message: '请输入用户名',
                    trigger: 'blur'
                  }],
          code: [{
                  required: true,
                  message: '请输入验证码',
                  trigger: 'blur'
                }]
        }
      } else if (activeKey.value === 'password') {
        return {
          username: [{
                      required: true,
                      min: 2,
                      max: 25,
                      pattern: '^[0-9a-zA-Z]+[_]*[0-9a-zA-Z]+$',
                      message: '账号为2-25个字母、数字、下划线组合字符'
                    }],
          password: [{
                      required: true,
                      min: 6,
                      max: 20,
                      pattern: '^[0-9a-zA-Z]+[_]*[0-9a-zA-Z]+$',
                      message: '密码为6-20个字母、数字、下划线组合字符'
                    }],
          code: [{
                  required: true,
                  min: 4,
                  max: 4,
                  pattern: '[0-9a-zA-Z]{4}',
                  message: '请正确输入验证码'
                }]
        }
      } else if (activeKey.value === 'phone') {
        return {
          phone: [{
                  required: true,
                  min: 11,
                  max: 11,
                  pattern: '^1[3-9][0-9]{9}$',
                  message: '手机号格式不正确'
                }],
          code: [{
                  required: true,
                  min: 6,
                  max: 6,
                  pattern: '[0-9a-zA-Z]{4}',
                  message: '请正确输入验证码'
                }]
        }
      }
    })

    const closed = () => {
      signRef.value && signRef.value.resetFields()
      formRef.value && formRef.value.resetFields()
      forRef.value && forRef.value.resetFields()
      emit('update:visible', false)
    }

    const timer = (num) => {
      DTIME && clearTimeout(DTIME)
      if (num >= 0) {
        coding.value = true
        codeTxt.value = `${num}s`
        DTIME = setTimeout(() => {
          timer(--num)
        }, 1000)
      } else {
        coding.value = false
        codeTxt.value = '获取验证码'
      }
    }

    const validatePhone = () => {
      if (coding.value) return
      formRef.value.validateFields(['phone']).then(() => {
        captmodel.value = true
      })
    }

    const handleSendSms = (captcha) => {
      if (!captcha) {
        message.error('请输入图形验证码')
        return
      }
      // loading.value = true
      sendSmsCode.send({
        phone: form.phone,
        captcha,
        scene: form.scene
      }).then(res => {
        // loading.value = false
        if (res && res.phone) {
          timer(60)
        }
      }).catch(err => {
        // loading.value = false
      })
    }

    const handleSubmit = () => {
      if (loading.value) return
      if (form.scene === 'reg') {
        signRef.value.validate().then(() => {
          loading.value = true
          userRegister.send({
            platform: window.utools ? 'UTOOL' : 'M',
            username: signForm.username,
            password: signForm.password,
            email: signForm.email,
            code: signForm.code,
            scene: signForm.scene,
            invite: WattTool.Api.getQueryString('invite')
          }).then((res) => {
            loading.value = false
            if (!res) return
            resulting.value = true
          }).catch(() => {
            loading.value = false
          })
        })
      } else if (form.scene === 'forget') {
        forRef.value.validate().then(() => {
          loading.value = true
          // 忘记密码触发
          userForgetPassword.send({
            username: form.username,
            scene: form.scene,
            code: form.code
          }).then((res) => {
            loading.value = false
            if (res) {
              message.success(`密码重置邮件已发送至 ${res} 邮箱，请注意查收`)
              closed()
            }
          }).catch(() => {
            loading.value = false
          })
        })
      } else if (activeKey.value === 'password') {
        formRef.value.validate().then(() => {
          loading.value = true
          userLogin.send({
            platform: window.utools ? 'UTOOL' : 'M',
            username: form.username,
            password: form.password,
            code: form.code,
            scene: form.scene,
          }).then(res => {
            loading.value = false
            const { uid, nickname, token, tokenExpired } = res
            ll.set('op_id', uid, { expires: new Date(tokenExpired) })
            ll.set('op_name', nickname, { expires: new Date(tokenExpired) })
            ll.set('token', token, { expires: new Date(tokenExpired) })
            closed()
          }).catch(() => {
            loading.value = false
          })
        })
      } else {
        formRef.value.validate().then(() => {
          loading.value = true
          loginBySmsCode.send({
            platform: window.utools ? 'UTOOL' : 'M',
            phone: form.phone,
            code: form.code,
            scene: form.scene,
          }).then(res => {
            loading.value = false
            const { uid, nickname, token, tokenExpired } = res
            ll.set('op_id', uid, { expires: new Date(tokenExpired) })
            ll.set('op_name', nickname, { expires: new Date(tokenExpired) })
            ll.set('token', token, { expires: new Date(tokenExpired) })
            closed()
          }).catch(() => {
            loading.value = false
          })
        })
      }
    }

    const resultClosed = () => {
      form.scene = 'login'
      resulting.value = false
    }

    return {
      resulting,
      show: modelVisible,
      form,
      formRef,
      forRef,
      signForm,
      signRef,
      rules,
      activeKey,
      loading,
      coding,
      captRef,
      codeTxt,
      captmodel,
      validatePhone,
      handleSendSms,
      handleSubmit,
      closed,
      resultClosed,
    }
  }
})
</script>
<style lang="less">
.login-title {
  width: 100%;
  height: 22px;
  line-height: 22px;
  display: flex;
  justify-content: space-between;
  .login-close {
    line-height: 22px;
  }
  &.login-reg {
    color: #1890ff;
    justify-content: center;
    .pre-icon {
      position: absolute;
      left: 8px;
      top: 15px;
      color: #1890ff;
      cursor: pointer;
    }
  }
}
.login-form {
  height: calc(100% - 80px);
  padding: 0 20px;
  text-align: left;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  .login-form-btn {
    margin-bottom: 0;
  }
  .go-reg {
    cursor: pointer;
    color: #1890ff;
  }
}
.login-title, .login-form {
  .pre-icon {
    color: rgba(0, 0, 0, 0.25);
    user-select: none;
  }
}
</style>
